package alpha.com.google.code.mechanic.janitor.ui;

import java.util.Set;

import org.eclipse.core.databinding.beans.PojoObservables;
import org.eclipse.core.databinding.observable.map.IObservableMap;
import org.eclipse.core.databinding.observable.set.IObservableSet;
import org.eclipse.core.databinding.property.Properties;
import org.eclipse.jface.databinding.viewers.ObservableMapLabelProvider;
import org.eclipse.jface.databinding.viewers.ObservableSetContentProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;

import alpha.com.google.code.mechanic.janitor.controller.ContextData;

import com.google.eclipse.mechanic.Task;

/**
 * The dialog is to allow the users to copy select key/value pairs to an
 * existing Task or to a new Task of a new Context.
 * 
 * Last_edited: Nov 6, 2014
 * 
 * @History:
 * 1. Time: Oct 5, 2014
 * @author jingjie jiang
 * 1) Delete the variable m_bindingContext.
 * 2) Change the return type of method initDataBindings() from DataBindingContext
 * to void.
 * 
 * 2. Add code to check Context name duplication.
 * @author jingjiejiang
 * @edited Nov 6, 2014
 * 1) add a private field: ContextData ctxData
 * 2) add checking code in the method: modifyText(ModifyEvent e) of the method
 * createTxtCtxName (Composite composite)
 *
 * @author jingjiejiang
 * @since Aug 17, 2014
 */
public class KeyPairsCopyDialog extends Dialog {
  
  private static final String COPY_KEYPAIRS_DIALOG_TITLE = "Copy key/value pairs"; 
  
  private Table tableDstnTask;
  private CheckboxTableViewer chkboxTblDstnTask;
  private Button btnChkCopyToNewCtx;
  // The value indicate whether the user want to copy the selected key/value
  // pairs to a new Task of a new Context.
  private boolean isCopyToNewCtx;
  private Combo comboTaskType;
  
  private Text textCtxName;
  private Text textTaskTitle;
  private Text textTaskDesc;
  private Text textTaskFileName;
  
  private String strCtxName;
  private String strTaskTitle;
  private String strTaskDesc;
  private String strTaskFileName;
  private int iTaskType;

  private Set<Task> setTask;
  // The selected Task.
  private Object[] selTask;
  private ContextData ctxData;
  
  /**
   * Create the dialog.
   * @param parentShell
   */
  public KeyPairsCopyDialog(Shell parentShell, Set<Task> setTask) {
    super(parentShell);
    this.setTask = setTask;
    isCopyToNewCtx = false;
    
    ctxData = new ContextData();
    try {
      ctxData.readContextsFile();
    } catch (Exception e) {
      MessageDialog.openError(getParentShell(), "Couldn't read the "
          + "context.con file.", e.getMessage());
    }
  }
  
  @Override
  public void create () {
    super.create();
    getButton(IDialogConstants.OK_ID).setEnabled(false);
  }
  
  @Override
  protected void configureShell (Shell shell) {
    super.configureShell(shell);
    if (COPY_KEYPAIRS_DIALOG_TITLE != null) {
      shell.setText(COPY_KEYPAIRS_DIALOG_TITLE);
    }
  }

  /**
   * Create contents of the dialog.
   * @param parent
   */
  @Override
  protected Control createDialogArea(Composite parent) {
    Composite container = (Composite) super.createDialogArea(parent);
    
    Composite composite = new Composite(container, SWT.NONE);
    GridData gd_composite = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
    gd_composite.heightHint = 225;
    gd_composite.widthHint = 338;
    composite.setLayoutData(gd_composite);
    
    chkboxTblDstnTask = CheckboxTableViewer.newCheckList(composite, SWT.BORDER | SWT.FULL_SELECTION);
    chkboxTblDstnTask.addCheckStateListener(new ICheckStateListener() {
      public void checkStateChanged(CheckStateChangedEvent event) {

        // Only allow to select one Task at a time.
        if (event.getChecked()) {
          chkboxTblDstnTask.setAllChecked(false);
          chkboxTblDstnTask.setChecked(event.getElement(), true);
          if (chkboxTblDstnTask.getCheckedElements().length != 0) {
            getButton(IDialogConstants.OK_ID).setEnabled(true);
          }
        }
        else {
          getButton(IDialogConstants.OK_ID).setEnabled(false);
        }

      }
    });
    tableDstnTask = chkboxTblDstnTask.getTable();
    tableDstnTask.setLinesVisible(true);
    tableDstnTask.setHeaderVisible(true);
    tableDstnTask.setBounds(0, 24, 338, 201);
    
    TableViewerColumn tblViewerClmnTaskName = new TableViewerColumn(chkboxTblDstnTask, SWT.NONE);
    TableColumn tblclmnTaskName = tblViewerClmnTaskName.getColumn();
    tblclmnTaskName.setWidth(320);
    tblclmnTaskName.setText("      Task name");
    
    createBtnChkCopyToNewCtx(composite);
    
    Label lblNewCtx = new Label(composite, SWT.NONE);
    lblNewCtx.setBounds(0, 30, 82, 14);
    lblNewCtx.setText("New Context:");
    
    Label lblNewCtxName = new Label(composite, SWT.NONE);
    lblNewCtxName.setBounds(0, 52, 82, 14);
    lblNewCtxName.setText("Context name:");
    
    createTxtCtxName(composite);
    
    Label label = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
    label.setBounds(0, 24, 338, 2);
    
    Label label_1 = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
    label_1.setBounds(0, 74, 338, 2);
    
    Label lblNewTask = new Label(composite, SWT.NONE);
    lblNewTask.setBounds(0, 82, 59, 14);
    lblNewTask.setText("New Task:");
    
    Label lblTaskTitle = new Label(composite, SWT.NONE);
    lblTaskTitle.setBounds(0, 136, 82, 14);
    lblTaskTitle.setText("Title:");
    
    createTxtTaskTtile(composite);
    
    Label lblTaskDesc = new Label(composite, SWT.NONE);
    lblTaskDesc.setBounds(0, 168, 74, 14);
    lblTaskDesc.setText("Description:");
    
    createTxtTaskDesc(composite);
    
    Label lblTaskType = new Label(composite, SWT.NONE);
    lblTaskType.setBounds(0, 201, 59, 14);
    lblTaskType.setText("Task Type:");
    
    createComboTaskType(composite);
    
    Label lblTskFileName = new Label(composite, SWT.NONE);
    lblTskFileName.setBounds(0, 102, 89, 14);
    lblTskFileName.setText("Task File Name:");
    
    createTxtTsKFileName(composite);
    
    Label lblNewLabel = new Label(composite, SWT.NONE);
    lblNewLabel.setBounds(313, 102, 25, 14);
    lblNewLabel.setText(".epf");
    
    initDataBindings();

    return container;
  }
  
  private void createTxtTsKFileName (Composite composite) {
    
    textTaskFileName = new Text(composite, SWT.BORDER);
    textTaskFileName.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        setOkBtnEnabledStatus();
      }
    });
    textTaskFileName.setBounds(88, 99, 222, 19);
    textTaskFileName.setEditable(false);
    textTaskFileName.setBackground(new Color(null, 204, 205, 207));
  }
  
  private void createComboTaskType (Composite composite) {
    
    comboTaskType = new Combo(composite, SWT.READ_ONLY);
    comboTaskType.setBounds(88, 198, 113, 22);
    String[] taskmod = {"Last Mod", "Reconcile"};
    comboTaskType.setItems(taskmod);
    comboTaskType.select(0);
  }
  
  private void createTxtTaskDesc (Composite composite) {
    
    textTaskDesc = new Text(composite, SWT.BORDER);
    textTaskDesc.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        
        setOkBtnEnabledStatus();
      }
    });
    textTaskDesc.setBounds(88, 165, 250, 19);
    textTaskDesc.setEditable(false);
    textTaskDesc.setBackground(new Color(null, 204, 205, 207));
  }
  
  private void createTxtTaskTtile (Composite composite) {
    
    textTaskTitle = new Text(composite, SWT.BORDER);
    textTaskTitle.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        
        setOkBtnEnabledStatus();
      }
    });
    textTaskTitle.setBounds(88, 133, 250, 19);
    textTaskTitle.setEditable(false);
    textTaskTitle.setBackground(new Color(null, 204, 205, 207));
  }
  
  private void createTxtCtxName (Composite composite) {
    
    textCtxName = new Text(composite, SWT.BORDER);
    textCtxName.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        
        String name = textCtxName.getText();
        
        if (false == name.equals("")) {
          if (ctxData.getContextsCollector().isValidCtxName(name)) {
            textTaskFileName.setEditable(true);
            textTaskFileName.setBackground(new Color(null, 255, 255, 255));
            textTaskTitle.setEditable(true);
            textTaskTitle.setBackground(new Color(null, 255, 255, 255));
            textTaskDesc.setEditable(true);
            textTaskDesc.setBackground(new Color(null, 255, 255, 255));
          } else {
            textTaskDesc.setEditable(false);
            textTaskDesc.setBackground(new Color(null, 204, 205, 207));
            textTaskTitle.setEditable(false);
            textTaskTitle.setBackground(new Color(null, 204, 205, 207));
            
            MessageDialog.openError(getParentShell(), "Error", "There "
                + "already exist a Context with the same name. Please "
                + "specify another name for the new Context."); 
          }
        }
        else {
          
          textTaskDesc.setEditable(false);
          textTaskDesc.setBackground(new Color(null, 204, 205, 207));
          textTaskTitle.setEditable(false);
          textTaskTitle.setBackground(new Color(null, 204, 205, 207));
          
        }
        
        setOkBtnEnabledStatus();
      }
    });
    textCtxName.setBounds(88, 49, 250, 19);
  }
  
  private void createBtnChkCopyToNewCtx (Composite composite) {
    
    btnChkCopyToNewCtx = new Button(composite, SWT.CHECK);
    btnChkCopyToNewCtx.addSelectionListener(new SelectionAdapter() {
      @Override
      public void widgetSelected(SelectionEvent e) {
        
      if (btnChkCopyToNewCtx.getSelection()) {
        chkboxTblDstnTask.getTable().setVisible(false);
        getButton(IDialogConstants.OK_ID).setEnabled(false);
      }
      else {
        chkboxTblDstnTask.getTable().setVisible(true);
        chkboxTblDstnTask.getTable().setFocus();
      }
        
      }
    });
    btnChkCopyToNewCtx.setBounds(0, 0, 234, 18);
    btnChkCopyToNewCtx.setText("Copy to a new Context and a new Task");
  }
  
  protected void initDataBindings() {

    ObservableSetContentProvider setContentProvider = new ObservableSetContentProvider();
    IObservableMap observeMap = PojoObservables.observeMap(setContentProvider.getKnownElements(), Task.class, "title");
    chkboxTblDstnTask.setLabelProvider(new ObservableMapLabelProvider(observeMap));
    chkboxTblDstnTask.setContentProvider(setContentProvider);

    IObservableSet selfSet = Properties.selfSet(Task.class).observe(setTask);
    chkboxTblDstnTask.setInput(selfSet);
  }
  
  private void setOkBtnEnabledStatus () {
    
    if (false == textCtxName.getText().equals("") &&
        false == textTaskTitle.getText().equals("") &&
        false == textTaskDesc.getText().equals("") &&
        false == textTaskFileName.getText().equals("")) {
      getButton(IDialogConstants.OK_ID).setEnabled(true);
    }
    else {
      getButton(IDialogConstants.OK_ID).setEnabled(false);
    }
  }
  
  public Object[] getSelTask () {
    return selTask;
  }
  
  public boolean isCopyToNewCtx () {
    return isCopyToNewCtx;
  }
  
  public String getStrCtxName() {
    return strCtxName;
  }

  public String getStrTaskTitle() {
    return strTaskTitle;
  }

  public String getStrTaskDesc() {
    return strTaskDesc;
  }

  public String getStrTaskFileName() {
    return strTaskFileName;
  }

  public int getTaskType() {
    return iTaskType;
  }
  
  /**
   * Create contents of the button bar.
   * @param parent
   */
  @Override
  protected void createButtonsForButtonBar(Composite parent) {
    createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
        true);
    createButton(parent, IDialogConstants.CANCEL_ID,
        IDialogConstants.CANCEL_LABEL, false);
  }

  /**
   * Return the initial size of the dialog.
   */
  @Override
  protected Point getInitialSize() {
    return new Point(362, 316);
  }
  
  @Override
  protected void okPressed () {
    
    if (true == btnChkCopyToNewCtx.getSelection()) {
      isCopyToNewCtx = true;
      
      strCtxName = textCtxName.getText();
      strTaskFileName = textTaskFileName.getText();
      strTaskTitle = textTaskTitle.getText();
      strTaskDesc = textTaskDesc.getText();
      iTaskType = comboTaskType.getSelectionIndex();
    }
    else {
      selTask = chkboxTblDstnTask.getCheckedElements();
    }
    
    super.okPressed();
  }

}
